

package com.maoshi.shop.groupbuy.multishop.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.maoshi.shop.bean.dto.ProdAndSkuListsDto;
import com.maoshi.shop.bean.enums.OfflineHandleEventType;
import com.maoshi.shop.bean.model.OfflineHandleEvent;
import com.maoshi.shop.bean.model.Product;
import com.maoshi.shop.bean.param.OfflineHandleEventAuditParam;
import com.maoshi.shop.common.annotation.SysLog;
import com.maoshi.shop.common.exception.MaoshiShopBindException;
import com.maoshi.shop.common.util.PageParam;
import com.maoshi.shop.groupbuy.comment.dto.GroupActivityDto;
import com.maoshi.shop.groupbuy.comment.dto.GroupProdAndSkuListDto;
import com.maoshi.shop.groupbuy.comment.enums.ActivityStatusEnum;
import com.maoshi.shop.groupbuy.comment.model.GroupActivity;
import com.maoshi.shop.groupbuy.comment.model.GroupProd;
import com.maoshi.shop.groupbuy.comment.service.GroupActivityService;
import com.maoshi.shop.groupbuy.comment.service.GroupProdService;
import com.maoshi.shop.security.multishop.util.SecurityUtils;
import com.maoshi.shop.service.OfflineHandleEventService;
import com.maoshi.shop.service.ProductService;
import lombok.RequiredArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 拼团活动表
 *
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/group/activity")
public class GroupActivityController {

    private final MapperFacade mapperFacade;
    private final ProductService productService;
    private final GroupProdService groupProdService;
    private final GroupActivityService groupActivityService;
    private final OfflineHandleEventService offlineHandleEventService;

    /**
     * 分页查询
     *
     * @param page             分页对象
     * @param groupActivityDto 拼团活动表
     * @return 分页数据
     */
    @GetMapping("/page")
    public ResponseEntity<IPage<GroupActivityDto>> getGroupActivityPage(PageParam<GroupActivityDto> page, GroupActivityDto groupActivityDto) {
        groupActivityDto.setShopId(SecurityUtils.getShopUser().getShopId());
        return ResponseEntity.ok(groupActivityService.getGroupActivityPage(page, groupActivityDto));
    }


    /**
     * 通过id查询拼团活动表
     *
     * @param groupActivityId id
     * @return 单个数据
     */
    @GetMapping("/info/{groupActivityId}")
    public ResponseEntity<GroupActivity> getById(@PathVariable("groupActivityId") Long groupActivityId) {
        return ResponseEntity.ok(groupActivityService.getById(groupActivityId));
    }

    /**
     * 新增拼团活动表
     *
     * @param groupActivity 拼团活动表
     * @return 是否新增成功
     */
    @SysLog("新增拼团活动表")
    @PostMapping
    public ResponseEntity<Long> save(@RequestBody @Valid GroupActivity groupActivity) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        Date now = new Date();
        // 未启用状态
        groupActivity.setStatus(2);
        groupActivity.setShopId(shopId);
        groupActivity.setCreateTime(now);
        groupActivity.setUpdateTime(now);
        groupActivityService.save(groupActivity);
        return ResponseEntity.ok(groupActivity.getGroupActivityId());
    }

    /**
     * 修改拼团活动表
     *
     * @param groupActivity 拼团活动表
     * @return 是否修改成功
     */
    @SysLog("修改拼团活动表")
    @PutMapping
    public ResponseEntity<Boolean> updateById(@RequestBody @Valid GroupActivity groupActivity) {
        return ResponseEntity.ok(groupActivityService.updateById(groupActivity));
    }

    /**
     * 通过id启用拼团活动
     *
     * @param groupActivityId id
     * @return 是否启用拼团活动
     */
    @SysLog("启用拼团活动")
    @PutMapping("/active/{groupActivityId}")
    public ResponseEntity<Boolean> activeGroupActivity(@PathVariable Long groupActivityId) {
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        if (groupActivity == null) {
            throw new MaoshiShopBindException("未找到此拼团活动信息");
        }
        // 获取活动中是否存在活动商品
        List<GroupProd> groupProdList = groupProdService.list(new LambdaUpdateWrapper<GroupProd>().eq(GroupProd::getGroupActivityId, groupActivity.getGroupActivityId()));
        if (CollectionUtil.isEmpty(groupProdList)) {
            throw new MaoshiShopBindException("启用失败，请至少选择一个活动商品");
        }
        // 启用状态
        groupActivity.setStatus(1);
        groupActivityService.updateById(groupActivity);
        return ResponseEntity.ok(true);
    }

    /**
     * 通过id删除拼团活动表
     *
     * @param groupActivityId id
     * @return 通过id删除拼团活动表
     */
    @SysLog("删除拼团活动表")
    @DeleteMapping("/{groupActivityId}")
    public ResponseEntity<Boolean> removeById(@PathVariable Long groupActivityId) {
        // 查看活动是否为失效状态或者活动结束
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        if (Objects.isNull(groupActivity)) {
            throw new MaoshiShopBindException("未找到此活动，请稍后重试");
        }
        if (!(Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.FINISHED.value()) ||
                Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.EXPIRED.value()) ||
                Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.NOT_STARTED.value()))) {
            throw new MaoshiShopBindException("该活动状态下不能进行删除");
        }
        groupActivityService.updateToDelete(groupActivityId);

        return ResponseEntity.ok(true);
    }

    /**
     * 获取活动商品的信息及商品下规格信息
     */
    @GetMapping("/getProdAndSkuLists")
    public ResponseEntity<List<GroupProdAndSkuListDto>> getProdAndSkuLists(@RequestParam List<Long> prodIds) {
        List<ProdAndSkuListsDto> prodAndSkuListsDtoList = productService.getProdAndSkuLists(prodIds);
        List<GroupProdAndSkuListDto> groupProdAndSkuLists = mapperFacade.mapAsList(prodAndSkuListsDtoList, GroupProdAndSkuListDto.class);
        return ResponseEntity.ok(groupProdAndSkuLists);
    }

    /**
     * 失效进行中的拼团活动
     */
    @SysLog("失效拼团活动")
    @PutMapping("/invalid/{groupActivityId}")
    public ResponseEntity<Boolean> invalidActivity(@PathVariable Long groupActivityId) {
        // 查看活动
        GroupActivity groupActivity = groupActivityService.getById(groupActivityId);
        if (Objects.isNull(groupActivity) || !Objects.equals(groupActivity.getActivityStatus(), ActivityStatusEnum.UNDER_WAY.value())) {
            throw new MaoshiShopBindException("失效失败，活动不在进行中无法进行失效操作");
        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        if (!Objects.equals(groupActivity.getShopId(), shopId)) {
            throw new MaoshiShopBindException("您无权操作此活动");
        }
        List<Product> productList = groupActivityService.invalidGroupActivity(groupActivity);

        // 获取该活动下的所有商品
        for (Product product : productList) {
            productService.removeProductCacheByProdId(product.getProdId());
        }
        return ResponseEntity.ok(true);
    }

    /**
     * 通过活动id获取下线信息
     */
    @GetMapping("/getOfflineHandleEventByActivityId/{activityId}")
    public ResponseEntity<OfflineHandleEvent> getOfflineHandleEventByActivityId(@PathVariable("activityId") Long activityId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.GROUP_BUY.getValue(), activityId);
        return ResponseEntity.ok(offlineHandleEvent);
    }

    /**
     * 违规商品提交审核
     */
    @PostMapping("/auditApply")
    public ResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        groupActivityService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason());
        return ResponseEntity.ok().build();
    }

}
